
#include <cstdio>
#include <string>

#include <promote/String.hpp>

#include "CRRBinomial.hpp"
#include "ExpiryCalculator.hpp"
#include "VanillaOption.hpp"

using namespace provident;

int main(void)
{
    CRRBinomial crr;
    double spotPrice(1190);
    double expiryYears(36.0/365);
    double strikePrice(1180);
    char type('C');
    char style('E');
    double riskFreeRate(0.0025);
    double volatility(0.1624);
    unsigned height(100);
    std::string text;

    while(true) {
        // Inputs
        printf("\n----> New calculation...\n");
        printf("Spot price [%g]: ", spotPrice);
        std::cin >> text;
        printf("%d\n", text.length());
        printf("Years til expiry [%g]: ", expiryYears);
        std::cin >> expiryYears;
        printf("Strike Price [%g]: ", strikePrice);
        std::cin >> strikePrice;
        printf("Type (C=call, P=put) [%c]: ", type);
        std::cin >> type;
        printf("Style (A=american, E=european) [%c]: ", style);
        std::cin >> style;
        printf("Risk-Free Rate [%g]: ", riskFreeRate);
        std::cin >> riskFreeRate;
        printf("Volatility [%g]: ", volatility);
        std::cin >> volatility;
        printf("Tree height [%u]: ", height);
        std::cin >> height;
        printf("Using inputs: spot=%g, yearsTilExpiry=%g, strike=%g, type=%c, style=%c, risk-free rate=%g, vol=%g, height=%u\n",
               spotPrice, expiryYears, strikePrice, type,
               style, riskFreeRate, volatility, height);

        VanillaOption option(promote::String("AAPL"),
                             promote::String("AAPL"),
                             expiryYears, strikePrice,
                             type == 'C' ? VanillaOption::CALL : VanillaOption::PUT,
                             style == 'A' ? VanillaOption::AMERICAN : VanillaOption::EUROPEAN,
                             100);
        CRRBinomial::Evaluation eval;
        crr.valuate(eval, option, spotPrice, volatility, riskFreeRate, static_cast<int>(height));

        // Results
        printf("Results: price=%g, delta=%g, gamma=%g, theta=%g\n",
               eval.theoreticalPrice(), eval.delta(),
               eval.gamma(), eval.theta());
    }

    return 0;
}

